package thinker.miracle.utils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;

/**
 * @author bo.chen
 *
 */
public class ValidateUtil {

	protected final static Logger logger = Logger.getLogger(ValidateUtil.class);

	/**
	 * 邮件正则
	 */
	protected final static String EMAIL_PATTERN = "\\w[-\\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\\.)+[A-Za-z]{2,14}";

	/**
	 * http正则
	 */
	protected final static String HTTP_PATTERN = "^((https|http|ftp|rtsp|mms)?:\\/\\/)[^\\s]+";

	/**
	 * 手机号码正则
	 */
	protected final static String PHONE_PATTERN = "0?(13|14|15|18)[0-9]{9}";

	/**
	 * 电话号码正则
	 */
	protected final static String TELEPHONE_PATTERN = "[0-9-()()]{7,18}";

	/**
	 * qq号码正则
	 */
	protected final static String QQCODE_PATTERN = "[1-9]([0-9]{5,11})";

	/**
	 * 邮编正则
	 */
	protected final static String POSTCODE_PATTERN = "\\d{6}";

	/**
	 * ip正则
	 */
	protected final static String IP_PATTERN = "(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)";

	/**
	 * 身份证号码正则
	 */
	protected final static String IDCARD_PATTERN = "\\d{17}[\\d|x]|\\d{15}";

	/**
	 * 日期正则
	 */
	protected final static String DATETIME_PATTERN = "\\d{4}(\\-|\\/|.)\\d{1,2}\\1\\d{1,2}";

	/**
	 * 数字正则
	 */
	protected final static String NUMBER_PATTERN = "-?[1-9]\\d*";

	/**
	 * 正整数正则
	 */
	protected final static String INTEGER_PATTERN = "[1-9]\\d*";

	/**
	 * 负整数正则
	 */
	protected final static String UNINTEGER_PATTERN = "-[1-9]\\d*";

	/**
	 * 用户名称正则
	 */
	protected final static String NAME_PATTERN = "[A-Za-z0-9_\\-\\u4e00-\\u9fa5]+";

	/**
	 * 0正则
	 */
	protected final static String ZERO_PATTERN = "0";
	
	/**
	 * 验证email
	 * 
	 * @param eamil
	 * @return
	 */
	public static boolean valiEmail(String email) {
		if (empty(email))
			return false;
		return regular(email,EMAIL_PATTERN);
	}

	/**
	 * 验证http连接
	 * 
	 * @param http
	 * @return
	 */
	public static boolean valiHttp(String http) {
		if (empty(http))
			return false;
		return regular(http,HTTP_PATTERN);
	}

	/**
	 * 验证电话号码
	 * 
	 * @param telephone
	 * @return
	 */
	public static boolean valiTelephone(String telephone) {
		if (empty(telephone))
			return false;
		return regular(telephone,TELEPHONE_PATTERN);
	}

	/**
	 * 验证手机号码
	 * 
	 * @param phone
	 * @return
	 */
	public static boolean valiPhone(String phone) {
		if (empty(phone))
			return false;
		return regular(phone,PHONE_PATTERN);
	}

	/**
	 * 验证qq号码
	 * 
	 * @param qqCode
	 * @return
	 */
	public static boolean valiQQCode(String qqCode) {
		if (empty(qqCode))
			return false;
		return regular(qqCode,QQCODE_PATTERN);
	}

	/**
	 * 验证 邮编号码
	 * 
	 * @param postCode
	 * @return
	 */
	public static boolean valiPostCode(String postCode) {
		if (empty(postCode))
			return false;
		return regular(postCode,POSTCODE_PATTERN);
	}

	/**
	 * 验证ip地址
	 * 
	 * @param ip
	 * @return
	 */
	public static boolean valiIp(String ip) {
		if (empty(ip))
			return false;
		return regular(ip,IP_PATTERN);
	}

	private static final int[] WI = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
	
	private static final char[] VALI_CODE = {'1', '0','X', '9', '8', '7', '6', '5', '4', '3', '2'};
	
	/**
	 * 验证身份正号码
	 * 
	 * @param idCard
	 * @return
	 * 
	 * 
	 * (1)S = Sum(Ai * Wi), i = 0, … , 16 ，先对前17位数字的权求和
	 * 		Ai:表示第i位置上的身份证号码数字值(0~9)
	 * 		Wi:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 （表示第i位置上的加权因子）
	 * (2)计算模	Y = mod(S, 11)
	 * (3)根据模	查找得到对应的校验码 　　Y: 0 1 2 3 4 5 6 7 8 9 10 　　校验码: 1 0 X 9 8 7 6 5 4 3 2
	 * 
	 */
	public static boolean valiIDCard(String idCard) {
		if (empty(idCard))
			return false;
		if( regular(idCard,IDCARD_PATTERN) ){
			char[] idCharArr = idCard.toCharArray();
			char lastCode = idCharArr[idCharArr.length-1];
			int s = 0 , i = 0 ;
			for( i = 0 ; i < idCharArr.length-1 ; i++){
				s += (Integer.parseInt(String.valueOf(idCharArr[i])) * Integer.parseInt(String.valueOf(WI[i])));
			}
			if(lastCode == VALI_CODE[s % 11]){
				return true;
			}
		}
		return false;
	}

	/**
	 * 验证时间格式
	 * 
	 * @param dateTime
	 * @return
	 */
	public static boolean valiDateTime(String dateTime) {
		if (empty(dateTime))
			return false;
		return regular(dateTime,DATETIME_PATTERN);
	}

	/**
	 * 验证数字
	 * 
	 * @param number
	 * @return
	 */
	public static boolean valiNumber(String number) {
		if (empty(number))
			return false;
		return regular(number,NUMBER_PATTERN);
	}

	/**
	 * 验证正整数
	 * 
	 * @param integer
	 * @return
	 */
	public static boolean valiInteger(String integer) {
		if (empty(integer))
			return false;
		return regular(integer,INTEGER_PATTERN);
	}

	/**
	 * 验证负整数
	 * 
	 * @param uninteger
	 * @return
	 */
	public static boolean valiUnInteger(String uninteger) {
		if (empty(uninteger))
			return false;
		return regular(uninteger,UNINTEGER_PATTERN);
	}

	/**
	 * 验证用户名称
	 * 
	 * @param name
	 * @return
	 */
	public static boolean valiName(String name) {
		if (empty(name))
			return false;
		return regular(name,NAME_PATTERN);
	}

	/**
	 * 验证等于0
	 * 
	 * @param zero
	 * @return
	 */
	public static boolean valiZero(String zero) {
		if (empty(zero))
			return false;
		return regular(zero,ZERO_PATTERN);
	}

	/**
	 * 字符串长度验证 0（包含） len （包含）之间
	 * 
	 * @param s
	 * @param len
	 * @return
	 */
	public static boolean valiLength(String s, int len) {
		boolean flag = false;
		if (s != null && s.length() <= len) {
			flag = true;
		}
		return flag;
	}

	/**
	 * 字符串长度验证 beginLen（包含） endLen （包含）之间
	 * 
	 * @param s
	 * @param len
	 * @return
	 */
	public static boolean valiStrLength(String s, int beginLen, int endLen) {
		boolean flag = false;
		if (s != null && s.length() <= endLen && s.length() >= endLen) {
			flag = true;
		}
		return flag;
	}

	/**
	 * 验证字符串为数字 并且在 min 和 max之间 （包含 min 和 max）
	 * 
	 * @param num	
	 * @param min	
	 * @param max	
	 * @return
	 */
	public static boolean valiNumberBetween(String num, Integer min, Integer max) {
		boolean flag = false;
		if (valiNumber(num) && min == null && Integer.parseInt(num) <= max) {
			flag = true;
		} else if (valiNumber(num) && max == null && Integer.parseInt(num) >= min) {
			flag = true;
		} else if (valiNumber(num) && Integer.parseInt(num) >= min && Integer.parseInt(num) <= max) {
			flag = true;
		} else if (!valiNumber(num)) {
			logger.error(num + " must be number", new Exception(num + " num must be number"));
		}
		return flag;
	}

	/**
	 * 执行正则表达式验证
	 * 
	 * @param str
	 *            被验证的字符串
	 * @param regular
	 *            正则表达式
	 * @return
	 */
	public static boolean regular(String str, String regular) {
		if (empty(str) || empty(regular))
			return false;
		Pattern pattern = Pattern.compile(regular);
		Matcher matcher = pattern.matcher(str);
		return matcher.matches();
	}

	/**
	 * 判断多个文件是否为空
	 * 
	 * @param arr
	 * @return
	 */
	public static boolean empty(String... arr) {
		for (String s : arr) {
			if (s != null && !"".equals(s)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 判断str是否是arr其中的一个  区分大小写
	 * 
	 * @param str
	 * @param arr
	 * @return
	 */
	public static boolean valiIn(String str,String...arr){
		if(arr == null || arr.length <= 0 || str == null)
			return false;
		for(String s : arr){
			if(str.equals(s)){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 判断str是否是arr其中的一个  不区分大小写
	 * 
	 * @param str
	 * @param arr
	 * @return
	 */
	public static boolean valiInIgnoreCase(String str,String...arr){
		if(arr == null || arr.length <= 0 || str == null)
			return false;
		for(String s : arr){
			if(str.equalsIgnoreCase(s)){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 判断是否是0或者1
	 * 
	 * @param sex
	 * @return
	 */
	public static boolean valiSex(String sex){
		if(empty(sex))
			return false;
		return valiIn(sex,"0","1");
	}
	
	/**
	 * 判断文件名称是否为图片
	 * 
	 * @param file
	 * @return
	 */
	public static boolean valiImage(String file) {
		if (file == null || file.indexOf(".") < 0)
			return false;
		String format = file.substring(file.lastIndexOf("."));
		return valiInIgnoreCase(format,".jpg",".png",".jpeg",".bmp",".gif");
	}
}
